package com.lipaluma.field.validator.impl.string;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.lipaluma.field.validator.ValidationError;
import com.lipaluma.field.validator.Validator;
import com.lipaluma.field.validator.strategies.SubStringMatcherValidationStrategy;

/**
 * Validates if a forbidden substring is contained in the String entry value. In this case, add a validation error.<br/>
 * We can choose different strategies like check substrings only on starting or ending or in the entry value.<br/>
 * Also, we can decide to check all of the substrings to unvalidate the entry.<br/>
 * <p>
 * To initialize SubStringsForbidden Validator : 
 * <ul>
 * <li>With annotation : add {@link SubStringForbidden} annotation on the field</li>
 * <li>on xml file : add element <br/><br/>
 * <code>&lt;subStringsForbidden strategy="STRATEGY_VALUE" all=""><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;substring>substring 1&lt;/substring><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;substring>substring 2&lt;/substring><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;...<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;substring>substring n&lt;/substring><br/>
 * &lt;/subStringsForbidden></code><br/><br/>
 * in <code>&lt;column></code> element.<br/>
 * <p>
 * The attributes strategy and all are optional.<br/>
 * STRATEGY_VALUE can takes these values : 
 * <ul>
 * <li>STARTS_WITH</li>
 * <li>ENDS_WITH</li>
 * <li>CONTAINS</li>
 * </ul>
 * </li>
 * </ul>
 * @author Mario
 */
public abstract class AbstractSubStringsForbiddenValidator implements Validator {

	private List<String> substrings = new ArrayList<String>();
	private SubStringMatcherValidationStrategy strategy;
	private boolean atLeastOne;
	
	public AbstractSubStringsForbiddenValidator() {}
	public AbstractSubStringsForbiddenValidator(List<String> substrings) {
		init(substrings, SubStringMatcherValidationStrategy.CONTAINS, false);
	}
	public AbstractSubStringsForbiddenValidator(String... substrings) {
		init(Arrays.asList(substrings), SubStringMatcherValidationStrategy.CONTAINS, false);
	}
	public AbstractSubStringsForbiddenValidator(List<String> substrings, SubStringMatcherValidationStrategy strategy) {
		init(substrings, strategy, false);
	}
	public AbstractSubStringsForbiddenValidator(List<String> substrings, SubStringMatcherValidationStrategy strategy, boolean atLeastOne) {
		init(substrings, strategy, atLeastOne);
	}
	
	protected void init(List<String> substrings, SubStringMatcherValidationStrategy strategy, boolean atLeastOne) {
		this.substrings.addAll(substrings);
		this.strategy = strategy;
		this.atLeastOne = atLeastOne;
	}

	public boolean validate(Object value, List<ValidationError> errors) {
		if(atLeastOne) {
			for(String substring : substrings) {
				if(!strategy.matches(value.toString(), substring))
					return true;
			}
			errors.add(new ValidationError("Error on validation value "+value+" : all forbiddens substrings appears"));
			return false;
		} else {
			for(String substring : substrings) {
				if(strategy.matches(value.toString(), substring)) {
					errors.add(new ValidationError("Error on validation value "+value+" with a forbidden substring : "+substring));
					return false;
				}
			}
			return true;
		}
	}

}
